﻿<!DOCTYPE HTML>
<html lang="zh">
<head>
<title>打开文件 - 语法 &amp; 使用 | AutoHotkey v2</title>
<meta name="description" content="The 打开文件 function opens a file to read specific content from it and/or to write new content into it." />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
<script type="text/javascript">$(function(){0<=window.navigator.userAgent.toLowerCase().indexOf("ucbrowser")&&CaoNiMaDeUc()})</script>
<style type="text/css">.fopt{width:4em;text-align:center}.fnum{width:4em;text-align:right}</style>
</head>
<body>

<h1>打开文件</h1>

<p>打开文件, 从其中读取特定内容和/或将新内容写入其中.</p>
<pre class="Syntax">file := <span class="func">打开文件</span>(Filename, Flags <span class="optional">, Encoding</span>)</pre>

<h2 id="Parameters">参数</h2>
<dl>

  <dt>Filename</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>要打开文件的路径, 如果未指定绝对路径则假定在 <a href="../Variables.htm#WorkingDir">内_工作目录</a> 中.</p>
    <p>如下所示, 指定一个(或两个) 星号来打开标准 输入(input)/输出(output)/错误(error) 流:</p>
    <pre>
打开文件("*", "r")   <em>; 标准输入</em>
打开文件("*", "w")   <em>; 标准输出</em>
打开文件("**", "w")  <em>; 标准错误</em></pre>
  </dd>

  <dt>Flags</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a>或<a href="../Concepts.htm#numbers">整数</a></p>
    <p>表示所需的访问模式的字符串, 后面跟着其他选项(中间有可选的空格或制表符); 或数字标志的组合(总和). 支持的值在下表中描述.</p>
  </dd>

  <dt>Encoding</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>如果文件没有 UTF-8 或 UTF-16 <a href="https://en.wikipedia.org/wiki/Byte_order_mark">字节顺序标记</a>, 或者使用了 <code>h</code>(handle) 标志, 读写文件时使用的代码页(带字节顺序标记的文件 AutoHotkey 自动识别, 指定的 <i>Encoding</i> 无效). 如果省略本参数, 则使用 <a href="../Variables.htm#FileEncoding">内_文件编码</a> 的当前值.</p>
  </dd>

</dl>

<h2>Flags</h2>

  <h3>访问模式(互斥的)</h3>
<table class="info">
  <tr>
    <th>Flag</th>
    <th>十进制</th>
    <th>十六进制</th>
    <th style="text-align:left">描述</th>
  </tr>
  <tr>
    <td class="fopt">r</td>
    <td class="fnum">0</td>
    <td class="fnum">0x0</td>
    <td><i>读取:</i> 当文件不存在时失败.</td>
  </tr>
  <tr>
    <td class="fopt">w</td>
    <td class="fnum">1</td>
    <td class="fnum">0x1</td>
    <td><i>写入:</i> 创建新文件, <b style="color:red">覆盖任意已存在的文件</b>.</td>
  </tr>
  <tr>
    <td class="fopt">a</td>
    <td class="fnum">2</td>
    <td class="fnum">0x2</td>
    <td><i>追加:</i> 如果文件不存在则创建新文件, 否则移动文件指针到文件末尾.</td>
  </tr>
  <tr>
    <td class="fopt">rw</td>
    <td class="fnum">3</td>
    <td class="fnum">0x3</td>
    <td><i>读取/写入:</i> 当文件不存在时创建新文件.</td>
  </tr>
  <tr>
    <td class="fopt">h</td>
    <td>&nbsp;</td>
    <td class="fnum">&nbsp;</td>
    <td>表示 <i>Filename</i> 是包装在对象中的文件句柄. 忽略共享模式标志, 并且不检查句柄表示的文件或流的字节顺序标记. 当文件对象销毁时, 当文件对象销毁时, 文件句柄 <b>不会</b> 自动关闭并且调用 <a href="../objects/File.htm#Close">Close</a> 没有效果. 注意当 <i>Filename</i> 是非搜寻设备(例如管道或通信设备) 的句柄时, 不应该使用 <a href="../objects/File.htm#Seek">Seek</a>, <a href="../objects/File.htm#Pos">Pos</a> 和 <a href="../objects/File.htm#Length">Length</a>.</td>
  </tr>
</table>

<h3>共享模式标志</h3>
<table class="info">
  <tr>
    <th>Flag</th>
    <th>十进制</th>
    <th>十六进制</th>
    <th style="text-align:left">描述</th>
  </tr>
  <tr>
    <td class="fopt" style="white-space:nowrap">-rwd</td>
    <td>&nbsp;</td>
    <td class="fnum">&nbsp;</td>
    <td>为读取, 写入和/或删除访问进行文件锁定. 可以使用 <code>r</code>, <code>w</code> 和 <code>d</code> 的任意组合. 指定 <code>-</code> 相当于指定 <code>-rwd</code>. 如果完全省略, 默认为共享所有访问.</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td class="fnum">0</td>
    <td class="fnum">0x0</td>
    <td>如果 <i>Flags</i> 是数值的, 缺少共享模式标志会让文件被锁定.</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td class="fnum">256</td>
    <td class="fnum">0x100</td>
    <td>共享 <i>读取</i> 访问.</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td class="fnum">512</td>
    <td class="fnum">0x200</td>
    <td>共享 <i>写入</i> 访问.</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td class="fnum">1024</td>
    <td class="fnum">0x400</td>
    <td>共享 <i>删除</i> 访问.</td>
  </tr>
</table>

<h3>行结束符(EOL) 选项</h3>
<table class="info">
  <tr>
    <th>Flag</th>
    <th>十进制</th>
    <th>十六进制</th>
    <th style="text-align:left">描述</th>
  </tr>
  <tr>
    <td class="fopt">`n</td>
    <td class="fnum">4</td>
    <td class="fnum">0x4</td>
    <td>读取时把 <code>`r`n</code> 替换为 <code>`n</code> 而写入时把 <code>`n</code> 替换为 <code>`r`n</code>.</td>
  </tr>
  <tr>
    <td class="fopt"><code>`r</code></td>
    <td class="fnum">8</td>
    <td class="fnum">0x8</td>
    <td>读取时把单独的 <code>`r</code> 替换为 <code>`n</code>.</td>
  </tr>
</table>

<h2 id="Return_Value">返回值</h2>
<p>类型: <a href="../objects/File.htm">File</a></p>
<p>返回值是一个封装文件打开句柄的新<a href="../objects/File.htm">文件对象</a>. 使用此对象的方法和属性来访问文件的内容.</p>

<h2 id="Errors">错误</h2>
<p>如果文件不能打开, 则抛出<a href="Throw.htm#Exception">异常</a>. 异常对象的 <code>Message</code> 是基于错误代码的, 可以从异常对象的 <code>Extra</code> 属性中检索.</p>

<h2 id="Remarks">备注</h2>
<p><a href="../objects/File.htm#ReadLine">File.ReadLine</a> 始终支持 <code>`n</code>, <code>`r`n</code> 和 <code>`r</code> 作为行结束符, 并且不将它们包含在返回值中, 无论是否使用 <code>`r</code> 或 <code>`n</code> 选项. 这些选项仅影响 <a href="../objects/File.htm#Read">File.Read</a> 返回的或由 <a href="../objects/File.htm#Write">File.Write</a> 或 <a href="../objects/File.htm#WriteLine">File.WriteLine</a> 写入的文本中的行结束符的转换.</p>
<p>当创建 UTF-8 或 UTF-16 文件时, 会写入字节顺序标记到文件中, <b>除非</b> <i>Encoding</i>(或当参数 <i>Encoding</i> 省略时, 则使用 <a href="FileEncoding.htm">内_文件编码</a>) 包含 <code>UTF-8-RAW</code> 或 <code>UTF-16-RAW</code>.</p>
<p>当以读取方式打开含有 UTF-8 或 UTF-16 字节顺序标记(BOM) 的文件时, 会把文件指针放置到这个标志后, 来从输出中排除 BOM. 因此, 在刚刚打开这样的文件时 <code>File.Pos</code> 可能为 3 或 2.</p>

<h2 id="Related">相关</h2>
<p><a href="FileEncoding.htm">设置文件编码</a>, <a href="../objects/File.htm">文件对象</a>, <a href="FileRead.htm">读文件</a></p>

<h2 id="Examples">示例</h2>

<div class="ex" id="ExWriteRead">
<p><a href="#ExWriteRead">#1</a>: 这是个可运行脚本, 它写入一些文本到文件, 然后从文件读取回内存(它提供了与这个 <a href="DllCall.htm#ExFile">动态库调用 示例</a>相同的功能):</p>
<pre>FileName := 文件选择框("S16",, "Create a new file:")
如果 (FileName = "")
    返回
try
    file := 打开文件(FileName, "w")
捕获 error
{
    信息框 "Can't open '" FileName "' 遍历 writing."
        . "`n`nError " error.Extra ": " error.Message
    返回
}
TestString := "This is a test 字符串.`r`n"  <em>; 通过这种方式写入内容到文件时, 要使用 `r`n 而不是 `n 来开始新行.</em>
file.Write(TestString)
file.Close()

<em>; 现在已经把内容写入文件了, 把它们读取回内存中.</em>
try
    file := 打开文件(FileName, "r-d") <em>; 读取文件 ("r"), 共享除了删除 ("-d") 外的所有访问权限</em>
捕获 error
{
    信息框 "Can't open '" FileName "' 遍历 reading."
        . "`n`nError " error.Extra ": " error.Message
    返回
}
CharsToRead := 字符串长度(TestString)
TestString := file.Read(CharsToRead)
file.Close()
信息框 "The following 字符串 was read from the file: " TestString</pre>
</div>

<div class="ex" id="ExReadLine">
<p><a href="#ExReadLine">#2</a>: 以只读模式打开脚本并读取它的首行:</p>
<pre>file := 打开文件(内_脚本全路径, "r")
信息框 file.ReadLine()</pre>
</div>

<div class="ex" id="ExStreams">
<p><a href="#ExStreams">#3</a>: 演示标准 input/output 流的用法:</p>
<pre><em>; 打开控制台窗口以进行此次演示:</em>
动态库调用("AllocConsole")
<em>; 打开应用程序的 stdin/stdout 流.</em>
stdin  := 打开文件("*", "r")
stdout := 打开文件("*", "w")
stdout.Write("Enter your query.`n\&gt; ")
stdout.Read(0) <em>; 清除写入缓冲区.</em>
query := 右修剪(stdin.ReadLine(), "`n")
stdout.WriteLine("Your query was '" query "'. Have a nice day.")
stdout.Read(0) <em>; 清除写入缓冲区.</em>
等待 5000
</pre>
</div>

</body>
</html>